package com.adk.backend.controller;

import com.adk.backend.annotation.RequiresPermission;
import com.adk.backend.common.Result;
import com.adk.backend.service.InventoryListService;
import com.adk.backend.service.impl.InventoryListServiceImpl;
import com.adk.backend.util.JwtUtil;
import com.adk.backend.util.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 库存管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/inventory")
public class InventoryListController {
    
    @Autowired
    private InventoryListService inventoryListService;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private LogUtil logUtil;
    
    /**
     * 查询库存列表
     */
    @RequiresPermission("list")
    @GetMapping("/list")
    public Result<List<Map<String, Object>>> getInventoryList(
            @RequestParam(required = false) Long whId,
            @RequestParam(required = false) Long orderId,
            @RequestParam(required = false) String batchCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("whId", whId);
            params.put("orderId", orderId);
            params.put("batchCode", batchCode);
            
            List<Map<String, Object>> list = inventoryListService.getInventoryList(params);
            return Result.success(list);
        } catch (Exception e) {
            log.error("查询库存列表失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据ID查询库存详情
     */
    @RequiresPermission("view")
    @GetMapping("/detail")
    public Result<Map<String, Object>> getInventoryDetail(@RequestParam Long id) {
        try {
            Map<String, Object> detail = inventoryListService.getInventoryDetailById(id);
            if (detail == null) {
                return Result.error("库存不存在");
            }
            return Result.success(detail);
        } catch (Exception e) {
            log.error("查询库存详情失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 保存库存（新增或更新）
     */
    @RequiresPermission("edit")
    @PostMapping("/save")
    public Result<Boolean> saveInventory(
            @RequestBody Map<String, Object> data,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Object idObj = data.get("id");
            Long inventoryId = idObj != null ? Long.valueOf(idObj.toString()) : null;
            
            // 如果是更新，获取旧值（用于日志记录）
            Integer oldQty = null;
            if (inventoryId != null && inventoryId > 0) {
                Map<String, Object> oldInventory = inventoryListService.getInventoryDetailById(inventoryId);
                if (oldInventory != null && oldInventory.get("qty") != null) {
                    oldQty = Integer.valueOf(oldInventory.get("qty").toString());
                }
            }
            
            Integer userId = getCurrentUserId(token);
            boolean success = ((InventoryListServiceImpl) inventoryListService).saveInventoryFromRefs(data, userId);
            if (success) {
                // 获取新值（更新时，从数据库获取最新的qty值）
                Integer newQty = null;
                if (inventoryId != null && inventoryId > 0) {
                    // 更新后从数据库获取最新的qty值
                    Map<String, Object> updatedInventory = inventoryListService.getInventoryDetailById(inventoryId);
                    if (updatedInventory != null && updatedInventory.get("qty") != null) {
                        newQty = Integer.valueOf(updatedInventory.get("qty").toString());
                    }
                } else if (data.get("qty") != null) {
                    // 新增时，使用传入的qty值
                    newQty = Integer.valueOf(data.get("qty").toString());
                }
                
                // 记录日志（与PHP逻辑一致：action_logs($_SESSION['userid'], "inventory_list", $id, "Updated", $get_old['qty'], $info['qty'])）
                // 注意：只有更新时才记录日志，且需要旧值和新值
                if (inventoryId != null && inventoryId > 0 && oldQty != null && newQty != null) {
                    logUtil.logAction(getCurrentUserIdLong(token), "inventory_list", inventoryId, "Updated", 
                        oldQty.toString(), newQty.toString());
                }
                return Result.success("Success", true);
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("保存库存失败", e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除库存
     */
    @RequiresPermission("del")
    @PostMapping("/del")
    public Result<Boolean> deleteInventory(
            @RequestParam Long id,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            boolean success = inventoryListService.deleteInventory(id);
            if (success) {
                // PHP中删除库存没有记录日志，这里也不记录
                return Result.success("Success.", true);
            } else {
                return Result.error("Del Error");
            }
        } catch (Exception e) {
            log.error("删除库存失败", e);
            return Result.error("Del Error");
        }
    }
    
    /**
     * 导入Excel文件（批量添加库存）
     */
    @RequiresPermission("edit")
    @PostMapping("/import")
    public Result<Map<String, Object>> importInventory(
            @RequestParam("file") MultipartFile file,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            Map<String, Object> result = inventoryListService.importInventoryFromExcel(file, userId);
            
            if (result.get("success") != null && (Boolean) result.get("success")) {
                // PHP中导入库存没有记录日志，这里也不记录
                return Result.success(result.get("message").toString(), result);
            } else {
                return Result.error(result.get("message").toString());
            }
        } catch (Exception e) {
            log.error("导入库存失败", e);
            return Result.error("导入失败：" + e.getMessage());
        }
    }
    
    /**
     * 导出库存列表（Excel）
     */
    @RequiresPermission("export")
    @GetMapping("/export")
    public void exportInventoryList(
            @RequestParam(required = false) Long whId,
            @RequestParam(required = false) Long orderId,
            @RequestParam(required = false) String batchCode,
            @RequestParam(defaultValue = "true") boolean includeWarehouse,
            @RequestParam(defaultValue = "true") boolean includeBatchCode,
            HttpServletResponse response) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("whId", whId);
            params.put("orderId", orderId);
            params.put("batchCode", batchCode);
            
            inventoryListService.exportInventoryList(response, params, includeWarehouse, includeBatchCode);
        } catch (Exception e) {
            log.error("导出库存列表失败", e);
            throw new RuntimeException("导出失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取当前用户ID（从token中获取）
     */
    private Integer getCurrentUserId(String token) {
        if (token == null || token.isEmpty()) {
            return null;
        }
        try {
            String jwtToken = token.startsWith("Bearer ") ? token.substring(7) : token;
            Long userId = jwtUtil.getUserIdFromToken(jwtToken);
            return userId != null ? userId.intValue() : null;
        } catch (Exception e) {
            log.error("解析token失败", e);
            return null;
        }
    }
    
    private Long getCurrentUserIdLong(String token) {
        if (token == null || token.isEmpty()) {
            return null;
        }
        try {
            String jwtToken = token.startsWith("Bearer ") ? token.substring(7) : token;
            return jwtUtil.getUserIdFromToken(jwtToken);
        } catch (Exception e) {
            log.error("解析token失败", e);
            return null;
        }
    }
    
    /**
     * 获取调拨库存列表（根据源仓库）
     */
    @RequiresPermission("view")
    @GetMapping("/transfer/inventory")
    public Result<List<Map<String, Object>>> getTransferInventoryList(@RequestParam Long fromWhId) {
        try {
            List<Map<String, Object>> list = inventoryListService.getTransferInventoryList(fromWhId);
            return Result.success(list);
        } catch (Exception e) {
            log.error("获取调拨库存列表失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 创建调拨单
     */
    @RequiresPermission("edit")
    @PostMapping("/transfer/create")
    public Result<Map<String, Object>> createTransfer(
            @RequestParam Long fromWhId,
            @RequestParam Long toWhId,
            @RequestBody List<Map<String, Object>> transferItems,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            Map<String, Object> result = inventoryListService.createTransfer(fromWhId, toWhId, transferItems, userId);
            
            if (result.get("success") != null && (Boolean) result.get("success")) {
                // PHP中创建调拨单没有记录日志，这里也不记录
                return Result.success("Success.", result);
            } else {
                return Result.error(result.get("message").toString());
            }
        } catch (Exception e) {
            log.error("创建调拨单失败", e);
            return Result.error("创建失败：" + e.getMessage());
        }
    }
    
    /**
     * 确认收货（执行调拨）
     */
    @RequiresPermission("edit")
    @PostMapping("/transfer/confirm")
    public Result<Boolean> confirmTransfer(
            @RequestParam Long transferId,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            try {
                boolean success = inventoryListService.confirmTransfer(transferId, userId);
                if (success) {
                    // PHP中确认调拨没有记录日志，这里也不记录
                    return Result.success("Success.", true);
                } else {
                    return Result.error("确认失败");
                }
            } catch (RuntimeException e) {
                // 处理错误消息，与PHP逻辑一致
                String errorMsg = e.getMessage();
                if (errorMsg != null && errorMsg.contains("Error, Inventory not enought")) {
                    return Result.error("Error, Inventory not enought.");
                } else if (errorMsg != null && errorMsg.contains("Error, already recvd")) {
                    return Result.error("Error, already recvd");
                } else {
                    return Result.error("Error, " + (errorMsg != null ? errorMsg : "未知错误"));
                }
            }
        } catch (Exception e) {
            log.error("确认调拨失败", e);
            return Result.error("确认失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取调拨单列表
     */
    @RequiresPermission("list")
    @GetMapping("/transfer/list")
    public Result<List<Map<String, Object>>> getTransferList(
            @RequestParam(required = false) Long fromWh,
            @RequestParam(required = false) Long toWh,
            @RequestParam(required = false) Integer isRecvd) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("fromWh", fromWh);
            params.put("toWh", toWh);
            params.put("isRecvd", isRecvd);
            
            List<Map<String, Object>> list = inventoryListService.getTransferList(params);
            return Result.success(list);
        } catch (Exception e) {
            log.error("获取调拨单列表失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取调拨单详情
     */
    @RequiresPermission("view")
    @GetMapping("/transfer/detail")
    public Result<Map<String, Object>> getTransferDetail(@RequestParam Long transferId) {
        try {
            Map<String, Object> detail = inventoryListService.getTransferDetail(transferId);
            if (detail == null) {
                return Result.error("调拨单不存在");
            }
            return Result.success(detail);
        } catch (Exception e) {
            log.error("获取调拨单详情失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取库存汇总
     */
    @RequiresPermission("list")
    @GetMapping("/summary")
    public Result<List<Map<String, Object>>> getInventorySummary(
            @RequestParam(required = false) Integer view,
            @RequestParam(required = false) Long whId) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("view", view);
            params.put("whId", whId);
            
            List<Map<String, Object>> list = inventoryListService.getInventorySummary(params);
            return Result.success(list);
        } catch (Exception e) {
            log.error("获取库存汇总失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取过期库存列表
     */
    @RequiresPermission("list")
    @GetMapping("/overdue")
    public Result<List<Map<String, Object>>> getOverdueInventory(
            @RequestParam(required = false) Long whId) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("whId", whId);
            
            List<Map<String, Object>> list = inventoryListService.getOverdueInventory(params);
            return Result.success(list);
        } catch (Exception e) {
            log.error("获取过期库存失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
}

